<?php

use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

/***************************************************************************************
 ************************************* 接口通用部分 *************************************
 ***************************************************************************************/

/**
 * @param $name
 * @param string $default
 * @param string $error_message
 * @return string
 * trim(post) 去除两边空格的post数据
 */
function IT($name='',$default='',$error_message=''){
    if ($name === '') {
        return Input::all();
    }
    $value = Input::get($name);
    if($value === null || $value === ''){
        $value = $default;
    }
    if($value === true){
        /*if (!$error_message){
           header('Access-Control-Allow-Origin:*');
            // 响应类型
            header('Access-Control-Allow-Methods:POST');
            // 响应头设置
            header('Access-Control-Allow-Headers:x-requested-with,content-type');
        }*/
        EE($error_message ? : $name . '为必填');
        return false;
    }
    if(!is_array($value)){
        $value = trim($value);
    }
    return $value;
}

function gmt_iso8601($time) {
    $dtStr = date("c", $time);
    $mydatetime = new \DateTime($dtStr);
    $expiration = $mydatetime->format(\DateTime::ISO8601);
    $pos = strpos($expiration, '+');
    $expiration = substr($expiration, 0, $pos);
    return $expiration."Z";
}

/**
 * json API 返回成功
 * @param string $msg
 * @param array $data
 * @return array
 */
function json_success($msg='OK', $data=[]){
    $return = [
        'status'	    => 1,
        'info'		    => $msg,
        'data'		    => (empty($data) ? null : $data),
        'api_version'   => config('basic.api_version'),
    ];
    // 隐藏过滤空
    // clear_null($return['data']);

    return $return;
}

/**
 * json API 返回失败
 * @param $msg
 * @param array $data
 * @return array
 */
function json_error($msg, $data=[]){
    $msg = $msg ? : '服务器错误，请稍后重试';
    $return =  [
        'status'	    => 0,
        'info'		    => $msg,
        'data'		    => empty($data) ? null : $data,
        'api_version'   => config('basic.api_version'),
    ];
    // clear_null($return['data']);
    return $return;
}

/**
 * @param string $data
 * 清楚数据内的null
 */
function clear_null(&$data = ''){
    $data = json_decode(json_encode($data),true);
    if ($data === null || $data === false) {
        $data = '';
    }
    if (is_array($data) && !empty($data)) {
        foreach ($data as &$v) {
            if ($v === null || $v === false) {
                $v = '';
            } else if (is_array($v)) {
                clear_null($v);
            } else {
                //
            }
        }
    }
}

/**
 * 检测图片类型
 * @param string $file
 * @return bool|string
 */
function check_img($file='')
{
    $filename = $file ? $file : $_FILES['img_file']['name'];
    $ext = strtolower(pathinfo($filename,PATHINFO_EXTENSION));
    if (!in_array($ext,['jpeg','png','jpg'])) {
        return false;
    }
    return $ext;
}

/**
 * 检测视频类型
 * @param string $file
 * @return bool|string
 */
function check_video($file='')
{
    $filename = $file ? $file : $_FILES['video_file']['name'];
    $ext = strtolower(pathinfo($filename,PATHINFO_EXTENSION));
    if (!in_array($ext,['3gp','avi','flv','movie','mp4','mov'])) {
        EE('不支持'.$ext.'的视频格式');
        return false;
    }
    return $ext;
}

/**
 * 获取 contentType
 * @param $ext
 * @return array
 */
function get_content_type($ext)
{
    switch ($ext) {
        case 'jpeg':
            $type = ['ContentType'=>'image/jpeg'];
            break;
        case 'png':
            $type = ['ContentType'=>'image/png'];
            break;
        case 'jpg':
            $type = ['ContentType'=>'image/jpeg'];
            break;
        case '3gp':
            $type = ['ContentType'=>'video/3gpp'];
            break;
        case 'avi':
            $type = ['ContentType'=>'video/x-msvideo'];
            break;
        case 'flv':
            $type = ['ContentType'=>'video/x-flv'];
            break;
        case 'movie':
            $type = ['ContentType'=>'video/x-sgi-movie'];
            break;
        case 'mp4':
            $type = ['ContentType'=>'video/mp4'];
            break;
        default:
            $type = ['ContentType'=>'image/jpeg'];
            break;
    }
    return $type;
}

/**
 * 图片上传通用方法
 * $upload_path  上传路径（例：'idcard'）
 * $upload_para  上传参数名
 * $upload_para_val  上传参数值
 */
function img_upload($upload_path, $upload_para, $upload_para_val = '')
{
    $web_url = IT($upload_para);
    //判断是否为有效网址
    if(filter_var($web_url,FILTER_VALIDATE_URL)){
        return $web_url;
    }

    $val = '';
    base64_upload($upload_path, $upload_para, function ($data) use (&$val) {
        $val = $data[0];
    });
    if (empty($val)) {
        EE('图片上传失败，请重试');
    }
    return $val;
}

/**
 *  base64 格式上传并写入文件 多文件上传
 * @param $type
 * @param $field
 * @param string $callback
 * @param string $bathPath
 * @return bool
 */
function base64_upload($type,$field,$callback = '',$bathPath = ''){
    $sBase64 = IT($field);
    $file_name_pre = '/Public/images/'.$type.'/'.date('Y-m-d').'/';
    if (!chmod_dir_path($file_name_pre)) {
        return false;
    }

    $return = array();
    if (empty($sBase64)) {
        @$callback('');
        return false;
    }
    if (!is_array($sBase64)) {
        $sBase64 = array($sBase64);
    }
    foreach ($sBase64 as $base64) {
        $typeInfo = get_base64_type_info($base64);
        if (strpos($base64 ,"base64,")) {
            $base64 = explode('base64,', $base64)[1];
        }
        $base64 = base64_decode($base64);
        if(empty($base64)) continue;

        //生成图片本地路径
        $fileType = $typeInfo['status'] ? $typeInfo['data']['file_type'] : '.png';
        $file_name = $file_name_pre . uniqid(date('Ymd') . rand('1000','9999')) . $fileType;
//      $file_name = $file_name_pre.uniqid(date('Ymd').rand('1000','9999')).'.png';

        //将图片base64数据流写入本地路径
        $save_path = '.' . $file_name;
        if (!file_put_contents($save_path,$base64)) {
            return false;
            break;
        }
        $return[] = 'http://'. $_SERVER['HTTP_HOST'] . $file_name;
    }
    @$callback($return);
    return true;
}

/**
 * 生成文件目录，并且为文件dirName的每一层目录赋予0777权限
 * @param $dir
 * @param $power
 * @return bool
 */
function chmod_dir_path($dir,$power = 0777){
    $path = './';
    $foldersArr = explode('/',$dir);
    foreach ($foldersArr as $k => $folderName){
        //没有名称的文件夹不创建
        if (empty($folderName)){
            continue;
        }
        //生成每一层的文件目录
        $path .= $folderName . '/';
        if ( !is_dir($path)){
            if ( !mkdir($path,$power,true)){
                return false;
                break;
            }
        }else{
            chmod($path,$power);
        }
    }
    return true;
}

/**
 * 获取文件base64数据流的头部文件信息(请求类型与文件后缀)
 * @param $base64
 * @return array
 */
function get_base64_type_info($base64)
{
    $info = ['status' => 0, 'info' => '', 'data' => []];

    $preg = '/data:(.*)?;base64/';
    preg_match_all($preg,$base64,$mats);
    if (!empty($mats[1][0])){
        $info['status'] = 1;
        $info['data']['request_header'] = $mats[1][0];
        $info['data']['file_type']      = '.'.substr($mats[1][0],strpos($mats[1][0],'/')+1,strlen($mats[1][0]));
    }
    return $info;
}

/**
 * base64编码
 * @param $string
 * @return mixed|string
 */
function urlsafe_b64encode($string)
{
    $data = base64_encode($string);
    $data = str_replace(array('+','/','='),array('-','_',''),$data);
    return $data;
}

/**
 * base64解码
 * @param $string
 * @return bool|string
 */
function urlsafe_b64decode($string)
{
    $data = str_replace(array('-','_'),array('+','/'),$string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

/**
 * 模拟 post 请求
 * @param $url
 * @param array $post_data
 * @param bool $header
 * @return mixed
 */
function curl_post($url,$post_data = array() , $header = false){
    $ch = curl_init(); //初始化curl
    curl_setopt($ch, CURLOPT_URL, $url);//设置链接
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置是否返回信息
    curl_setopt($ch, CURLOPT_POST, 1);//设置为POST方式
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    if($header){
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));//POST数据
    $response = curl_exec($ch);//接收返回信息
    if(curl_errno($ch)){	//出错则显示错误信息
        print curl_error($ch);
    }
    curl_close($ch); //关闭curl链接
    return $response;
}

/**
 * 模拟 get 请求
 * @param $url
 * @return mixed
 */
function curl_get($url){
    $ch = curl_init(); //初始化curl
    curl_setopt($ch, CURLOPT_URL, $url);//设置链接
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置是否返回信息
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    $response = curl_exec($ch);//接收返回信息
    if(curl_errno($ch)){	//出错则显示错误信息
        print curl_error($ch);
    }
    curl_close($ch); //关闭curl链接
    return $response;
}

function hw_request($url, $postData = [], $header = [], $formUrlencoded = false)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if ($header) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }


    if ($postData) {

        curl_setopt($ch, CURLOPT_POST, true);
        //如果不用http_build_query你就会踩到坑的，你可以试试
        if($formUrlencoded){
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
        }else{
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }
    }

    $response  = curl_exec($ch);
    if ($errno = curl_errno($ch)) {
        $error = curl_error($ch);
        $this->errmsg = $error;
        $this->errno = $errno;
        curl_close($ch);

        return false;
    }
    curl_close($ch);

    return $response ;
}

/**
 * @param $url
 * @param null $data
 * @return mixed
 * */
function https_request_s($url, $data = null)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data))
    {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
}

/**
 * @param $url
 * @param null $data
 * @return mixed
 * */
function async_https_request_s($url, $data = null)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curl, CURLOPT_TIMEOUT_MS, 155);
    if (!empty($data))
    {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_exec($curl);
    curl_close($curl);
}


/**
 * @param $url
 * @return array
 * 下载微信文件
 */
function downloadWeixinFile($url)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_NOBODY, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $package = curl_exec($ch);
    $httpinfo = curl_getinfo($ch);
    curl_close($ch);
    return array_merge(array('body' => $package), array('header' => $httpinfo));
}

/**
 * @param $url
 * @param $save_path // ./开头
 * @return string	// 项目根目录起始的新文件名
 * curl 下载小文件，
 * 示例：
 * curl_download('http://wx.qlogo.com/xxx.jpg','./Public/upload/avatar')
 */
function curl_download($url,$save_path){
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    $fileSteam = curl_exec($ch);
    if(curl_errno($ch)){	//出错则显示错误信息
        print curl_error($ch);
    }
    curl_close($ch); //关闭curl链接
    $file_name_pre = $save_path.'/'.time2date_date(time()).'/';
    if(!is_dir($file_name_pre)){
        mkdir($file_name_pre);
    }
    $file_name = $file_name_pre.uniqid().'.jpg';
    file_put_contents($file_name,$fileSteam);
    $file_url = 'http://'.I('server.HTTP_HOST').substr($file_name,1);
    return $file_url;
}

/**
 * 对象转数组
 * @param $object
 * @return mixed
 */
function object_to_array($object)
{
    //先编码成json字符串，再解码成数组
    return json_decode(json_encode($object), true);
}



/**
 * 时间字符串
 * @param null $time
 * @return false|string
 */
function time2date($time = null){
    return date('Y-m-d H:i:s',$time ?? $_SERVER['REQUEST_TIME']);
}

/**
 * 日期字符串
 * @param null $time
 * @return false|string
 */
function time2date_date($time = null){
    return date('Y-m-d',$time ?? $_SERVER['REQUEST_TIME']);
}
/**
 * 数组 转 对象
 *
 * @param array $arr 数组
 * @return object
 */

function array_to_object($arr) {
    if (gettype($arr) != 'array') {
        return;
    }
    foreach ($arr as $k => $v) {
        if (gettype($v) == 'array' || getType($v) == 'object') {
            $arr[$k] = (object)array_to_object($v);
        }
    }

    return (object)$arr;
}

/**
 * 判断客户端的系统
 * @return string
 *
 */
function get_device_type()
{
    //全部变成小写字母
    $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    $type = 'other';
    //分别进行判断
    if(strpos($agent, 'iphone') || strpos($agent, 'ipad'))
    {
        $type = 'ios';
    }

    if(strpos($agent, 'android'))
    {
        $type = 'android';
    }
    return $type;
}
/**
 * 前端JS解密用
 */
function unescape($str)
{
    $ret = '';
    $len = strlen($str);
    for ($i = 0; $i < $len; $i ++)
    {
        if ($str[$i] == '%' && $str[$i + 1] == 'u')
        {
            $val = hexdec(substr($str, $i + 2, 4));
            if ($val < 0x7f)
                $ret .= chr($val);
            else
                if ($val < 0x800)
                    $ret .= chr(0xc0 | ($val >> 6)) .
                        chr(0x80 | ($val & 0x3f));
                else
                    $ret .= chr(0xe0 | ($val >> 12)) .
                        chr(0x80 | (($val >> 6) & 0x3f)) .
                        chr(0x80 | ($val & 0x3f));
            $i += 5;
        } else
            if ($str[$i] == '%')
            {
                $ret .= urldecode(substr($str, $i, 3));
                $i += 2;
            } else
                $ret .= $str[$i];
    }
    return $ret;
}
//获取当月的第一天和最后一天
function getthemonth($date)
{
    $firstday = date('Y-m-01', strtotime($date));
    $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));
    return array($firstday,$lastday);
}

/***************************************************************************************
 ************************************* laravel->tp *************************************
 **************************************** begin ****************************************
 ***************************************************************************************/
/**
 * 异常处理
 * @param $msg
 * @throws Exception
 */
function EE($msg, $error_code=0)
{
    $e_msg = '';
    if(is_string($msg)){
        $e_msg = $msg;
    } else {
        $e_msg = json_encode($msg);
    }
    header('Access-Control-Allow-Origin:*');
    // 响应类型
    header('Access-Control-Allow-Methods:POST');
    // 响应头设置
    header('Access-Control-Allow-Headers:Origin, Content-Type, Cookie, Accept, X-Requested-With');
    throw new \App\Exceptions\ApiException($e_msg, $error_code);
}

/**
 * 表名
 * @param string $table
 * @return mixed
 */
function D($table='users')
{
    return DB::table($table);
}

/***************************************************************************************
 ************************************* laravel->tp *************************************
 ***************************************** end *****************************************
 ***************************************************************************************/


/**
 * @param $str
 * @return mixed
 * 字符串转ascii
 */
function str_to_ascii($str){
    $str = mb_convert_encoding($str,'UTF-8');
    $change_after = '';
    for($i = 0; $i<strlen($str); $i++){
        $temp_str = dechex(ord($str[$i]));
        $change_after .= $temp_str[1].$temp_str[0];
    }
    return strtoupper($change_after);
}

/**
 * @param $ascii
 * @return string
 * ascii转字符串
 */
function ascii_to_str($ascii){
    $asc_arr = str_split(strtolower($ascii),2);
    $str = '';
    for($i = 0; $i<count($asc_arr); $i++){
        $str .= chr(hexdec($asc_arr[$i][1].$asc_arr[$i][0]));
    }
    return mb_convert_encoding($str,'UTF-8','GB2312');
}

/**
 * @param int $type
 * @return mixed
 * 获取客户端IP
 */
function get_client_ip($type = 0) {
    $type       =  $type ? 1 : 0;
    static $ip  =   NULL;
    if ($ip !== NULL) return $ip[$type];
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos    =   array_search('unknown',$arr);
        if(false !== $pos) unset($arr[$pos]);
        $ip     =   trim($arr[0]);
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip     =   $_SERVER['HTTP_CLIENT_IP'];
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/**
 * @param string $id
 * @param int $expire
 * @return string
 * 缓存时间为1分钟
 */
function create_smscode($id = '',$expire = 1){
    $codeSet = '123456789';
    $code = '';
    for($i=0;$i<5;$i++){
        $rand = rand(1,strlen($codeSet));
        $code .= $codeSet{$rand-1};
    }
    /*if(config('app.test')){
        $code = 88888;//测试
    }*/
    if(cache('bind_sms_'.$id)){
        return cache('bind_sms_'.$id);
    }
    cache(['bind_sms_'.$id => $code], $expire);
    return $code;
}

/**
 * @param string $id
 * @param $code
 * @return bool
 * 检查短信验证码是否正确
 */
function check_smscode($mobile = '',$code){
    $session_code = cache('bind_sms_'.$mobile);
    if($code != $session_code){
        return false;
    }else{
        return true;
    }
}

/**
 * @param $mobile
 * @param $content
 * @return bool
 * 发送短信验证码
 */
function send_msg($mobile, $code)
{
    if(env('APP_ENV') == 'pro')//正式环境发短信
    {
        $url = 'http://sms.ivy.xn--3ds443g';
    }
    else {//开发环境和测试环境发短信
        $url = 'http://sms-dev.ivy.xn--3ds443g';
    }
    $param = array(
        'account' => 'ivy.xn--3ds443g',//不要更改
        'key'     => 'fe4035d0a78ca8e0ed6b45876c6b9e3b',//不要更改
        'time'    => time(),//当前服务器时间戳
        'mobile'  => $mobile,//手机号码
        'tpl_id'   =>  '84960',
        'tpl_value' => urlencode("#app#=i微影&#code#={$code}"),//短信内容
    );
    $info = base64_encode(json_encode($param));
    $data = ['info' => $info];
    $res = https_request_s($url, $data);
    $result = json_decode($res, true);
    if($result['state']){
        return true;
    }else{
        return false;
    }
}

/**
 * 发送邀请短信
 * @param $mobile
 * @return bool
 */
function send_invite_msg($mobile)
{
    $flag = 0;
    $params='';//要post的数据

    $argv = array(
        'name'=>'13362738868',     //必填参数。用户账号
        'pwd'=>'1C2C5ED2E5E2D93A01067BDF5FF4',     //必填参数。（web平台：基本资料中的接口密码）
        'content'=>'最近身边朋友都在使用一款名叫【i微影】的记录人生APP，为不留遗憾，你也赶快点击他们官网:http://t.cn/EPxo0aQ 免费下载免费使用吧，回T退订！',   //必填参数。发送内容（1-500 个汉字）UTF-8编码
        'mobile'=>$mobile,   //必填参数。手机号码。多个以英文逗号隔开
        'stime'=>'',   //可选参数。发送时间，填写时已填写的时间发送，不填时为当前时间发送
        'sign'=>'',    //必填参数。用户签名。
        'type'=>'pt',  //必填参数。固定值 pt
        'extno'=>''    //可选参数，扩展码，用户定义扩展码，只能为数字
    );

    foreach ($argv as $key=>$value) {
        if ($flag!=0) {
            $params .= "&";
        }
        $params.= $key."=";
        $params.= urlencode($value);// urlencode($value);
        $flag = 1;
    }

    $url = "http://sms.1xinxi.cn/asmx/smsservice.aspx?".$params;
    $con= substr( file_get_contents($url), 0, 1 );

    return $con == '0';
}

/**
 * 根据用户id获取当前新ticket
 */
function get_ticket(int $uid)
{
    $ClientSource = Input::get('ClientSource',3);
    $ClientSystem = Input::get('ClientSystem','MicroMessenger');
//    $ticket = cache('ticket_'.$ClientSource.$uid);
//    if($ticket){
//        return $ticket;
//    }
    $user_ticket_info = DB::table('user_tickets')
        ->where([
            ['client_source','=',$ClientSource],
            ['uid','=',$uid]
        ])
        ->first();
    if($user_ticket_info){
        $ticket = guid();
        $data = array(
            'ticket' => $ticket,
            'updated_at'    => date('Y-m-d H:i:s',time()),
            'status' => 1
        );
        DB::table('user_tickets')->where('uid', '=',$uid)->update($data);

        cache(['ticket_'.$ClientSource.$uid => $ticket], config('basic.ticket_cache_time'));

        return $ticket;
    }else{
        $ticket = guid();
        $sso = array(
            'ticket' => $ticket,
            'uid' => $uid,
            'status' => 1, //{活动中=1,正常退出=2,异常=0}
            'ip_address' => get_ip(),
            'client_source' => $ClientSource,
            'client_system' => $ClientSystem,
            'created_at'    => date('Y-m-d H:i:s',time()),
            'updated_at'    => date('Y-m-d H:i:s',time())
        );
        $result = DB::table('user_tickets')->insertGetId($sso);
        if($result){
            cache(['ticket_'.$ClientSource.$uid => $ticket], config('basic.ticket_cache_time'));
            return $ticket;
        }
        return '';
    }
}

/**
 * @param $ticket
 * @return \Illuminate\Cache\CacheManager|mixed
 *
 */
function get_uid_by_ticket($ticket){
    $uid = cache('uid_by_ticket_'.$ticket);
    if(!$uid){
        $uid = DB::table('user_tickets')->where([['ticket','=',$ticket]])->value('uid');
        cache(['uid_by_ticket_'.$ticket],24*60);
    }
    return $uid;
}

/**
 * @return string
 * 生成 guid / uuid
 */
function guid(){
    if (function_exists('com_create_guid')){
        return trim(com_create_guid(),'{}"');
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"

        $uuid = substr($charid, 0, 9).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,19,12);
        return $uuid;
    }
}

/**
 * @return array|false|string
 * 得到客户端ip
 */
function get_ip() {
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) $ip = getenv("REMOTE_ADDR");
    else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) $ip = $_SERVER['REMOTE_ADDR'];
    else $ip = "127.0.0.1";
    return ($ip);
}

/**
 * @param $id
 * @param $mobile
 * @return string
 * ticket 加密
 */
function creat_ticket($id,$mobile){
    $arr = [
        'id' => base64_encode($id),
        'mobile' => base64_encode($mobile),
        'rand' => rand(1000,9999),
        'time' => time2date(),
        'ticket_key' => config('app.ticket_key'),
    ];
    $str = json_encode($arr);
    return encrypt($str);
}

/**
 * @param $ticket
 * @return array|bool
 * 检查ticket合法性
 */
function check_ticket($ticket){
    $arr = json_decode(decrypt($ticket),true);
    $id = base64_decode($arr['id']);
    $mobile = base64_decode($arr['mobile']);
    $flag_id = strlen(intval($id)) >= 7 ? true : false;
    $flag_mobile = strlen($mobile) == 11 ? true : false;
    if($flag_id && $flag_mobile){
        return [
            'uid' => $id,
            'mobile' => $mobile,
        ];
    }
    return false;
}

/**
 * @param $password
 * @return bool
 * 验证密码格式合法性
 */
function check_password_format($password){
    if(preg_match("/^([a-zA-Z0-9]|[_]){6,16}$/",$password)){
        return true;
    }
    return false;
}

/**
 * @return mixed
 * 获取access_token
 */
function curl_get_access_token()
{
    $oauth = config('auth.weixin');
    $appid = $oauth['appid'];
    $appsecret = $oauth['appsecret'];
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    $jsoninfo = json_decode($output, true);
    if (! isset($jsoninfo['access_token'])) {
        return false;
    }
    $access_token = $jsoninfo["access_token"];
    return $access_token;
}


/**
 * @return mixed
 * 获取access_token
 */
function accesstoken()
{
    $times = time();
    $get = DB::table('wechat_accesstoken')->where([['end_time','>',$times],['is_delete','=',0]])->first();
    if($get)
    {
        $token = $get->accesstoken;
    }else{
        $end_time = $times + 7200;
        $token = curl_get_access_token();
        $res= DB::table('wechat_accesstoken')->where([['end_time','<=',$times],['is_delete','=',0]])->delete();
        if(!$res)//若不支持删除数据内容,则改变状态
        {
            DB::table('wechat_accesstoken')->where([['end_time','<=',$times],['is_delete','=',0]])->update(['is_delete'=>1]);
        }
        $data = [
            'create_time' => $times,
            'end_time'      => $end_time,
            'accesstoken'   => $token
        ];
        DB::table('wechat_accesstoken')->insert($data);
    }
    return $token;
}

/**
 * @param $url
 * @return mixed|string
 *
 */
function curl_https_request($url)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    if (curl_errno($curl)) {return 'ERROR '.curl_error($curl);}
    curl_close($curl);
    $datas = json_decode($data,true);
    return $datas;
}

//通用提示页面
function html_notice($text='',$title=''){
    $html = <<<EOT
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <meta http-equiv="content-type" name="keywords" content="">
    <meta http-equiv="content-type" name="description" content="">
    <meta http-equiv="X-UA-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <title>{$title}</title>
</head>
<body>
<style>
body,html{
    background:#f1f1f1;
    height: 100%;
}
div{
    margin:0 auto;
    text-align: center;
}
img{
    width: 6rem;
    padding-top: 2.5rem;
    padding-bottom: 0.8rem;
}
p{
    padding-left: 0.9rem;
    padding-right: 0.9rem;
    line-height: 2rem;
}
</style>
    <div>
      <p>{$text}</p>
    </div> 
</body>
</html>
EOT;
    exit($html);
}


/**
 * json API 根据变量自动判断返回成功或失败
 * @param $var
 * @param string $error_msg
 * @param string $success_msg
 * @param array $data
 * @return array
 */
function json_return($var,$error_msg = '服务器错误，请稍后重试',$success_msg = '操作完成',$data = []){
    if($var === false || $var === null){
        return json_error($error_msg,$data);
    }else{
        return json_success($success_msg,$data);
    }
}

/**
 * 记文件形式调试信息,也可用于记录日志
 * @param $data //内容
 * @param string $filename //文件存放名称 自动加上日期文件夹
 */
function filedebug($data , $filename='filedebug.php'){
    $filepath = './log/'.$filename;
    // 如果是日志，则将日志分隔成日期文件夹
    $date = date('Ym/d');
    $filepath = str_replace('log/' , "log/$date/" , $filepath);
    $have = strripos($filepath , '/');
    $path = (false === $have ? '' :  substr($filepath , 0 , $have+1)); // 文件夹
    $file = end(explode('/',$filepath)) ?:'default.php'; // 文件名
    if($path && !is_dir($path)){
        mkdir($path,0777,true);
    }
    $filepath = $path . $file;
    $f = fopen($filepath , 'a+');
    fwrite($f , date('Y-m-d H:i:s').'----------'."\n");
    fwrite($f , var_export($data , true));
    fwrite($f , "\n".'----------'."\n");
    fclose($f);
}

function is_json($str)
{
    json_decode($str);

    return (json_last_error()==JSON_ERROR_NONE);
}

/**
 * 格式化时间
 * @param int $duration 时长 单位：秒
 * @return string
 */
function parseDuration($duration = 0)
{
    $minute = '00';

    if ($duration > 3600) {
        $hour = parseNum(floor($duration / 3600));
        $duration = $duration % 3600;
    }

    if ($duration > 60) {
        $minute = parseNum(floor($duration / 60));
        $duration = $duration % 60;
    }

    $duration = parseNum($duration);

    return isset($hour) ? ($hour . ':' . $minute . ':' . $duration) : ($minute . ':' . $duration);
}

/**
 * 格式化时长转化成秒
 * @param string $duration
 * @return int
 */
function duration2int($duration = '')
{
    $duration = explode(':', $duration);
    if (count($duration) <= 1) {
        return 0;
    }

    if (count($duration) === 2) {
        return $duration[0] * 60 + $duration[1];
    }

    return $duration[0] * 3600 + $duration[1] * 60 + $duration[2];
}

/**
 * 格式化小于10的数
 * @param int $num 数字
 * @return int|string
 */
function parseNum($num = 0)
{
    return $num > 9 ? $num : ('0' . $num);
}

/**
 * 获取随机数字字符串
 * @param int $length
 * @return string
 */
function random_num($length = 0)
{
    $str = '1234567890';
    $string = '';
    for ($i = 0; $i < $length; $i++) {
        $string .= $str[rand(0, 9)];
    }

    return $string;
}

/*
 * 图片转base64
 * */
function imgToBase64($img_file) {
     $img_base64 = '';
     if (file_exists($img_file)) {
                 $app_img_file = $img_file; // 图片路径
         $img_info = getimagesize($app_img_file); // 取得图片的大小，类型等

         //echo '<pre>' . print_r($img_info, true) . '</pre><br>';
         $fp = fopen($app_img_file, "r"); // 图片是否可读权限

         if ($fp) {
                         $filesize = filesize($app_img_file);
             $content = fread($fp, $filesize);
             $file_content = chunk_split(base64_encode($content)); // base64编码
             switch ($img_info[2]) {           //判读图片类型
                case 1: $img_type = "gif";
                     break;
                case 2: $img_type = "jpg";
                     break;
                case 3: $img_type = "png";
                     break;
             }

             $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码
         }
         fclose($fp);
     }
     return $img_base64; //返回图片的base64
 }


/**
 * 解析媒体域名
 * @param string $mediaUrl
 * @return mixed
 */
function parseUrl($mediaUrl = '')
{
    $data = parse_url($mediaUrl);
    if (!isset($data['host'])) {
        return '';
    }
    return ['bucketName' => substr($data['host'], 0, strpos($data['host'], '.')), 'ossKey' => substr($data['path'], 1)];
}

/**
 * 获取视频或图片签名可访问链接
 * @param $url
 * @return string
 */
function getSignUrl($url)
{
    // 判断是否开启cdn加速
    if(config('basic.oss_cdn.oss_cdn_enable') == true){
        $url = oss_cdn($url);
    }else{
        // 每个设备号+每个头像（或者视频）地址 一个key
        $mobile_unique_code = Input::get('mobile_unique_code');
        $key = md5($mobile_unique_code.$url);
        if (strpos($url, 'oss-cn-shenzhen.aliyuncs.com') !== false) {
            $time = time();
            $ossData = parseUrl($url);
            $duration = 3600;
            $expire = 3000;

            $url = \App\Services\Sts::getSignUrl($ossData['ossKey'], $duration, $ossData['bucketName']);
            // Redis::setex('signUrl:'.$key, $expire, $url);
        }
    }
    date_default_timezone_set(config('app.timezone'));  // 在阿里云SDK里修改出现时间过期问题
    return $url;
}

/*
 * oss cdn 加速
 * */
function oss_cdn($url)
{
    $oss_config = config('basic.oss_config');
    $cdn_config = config('basic.oss_cdn');
    if (strpos($url, $oss_config['sts_endpoint']) !== false) {
        $oss_butkey_url = 'http://'.$oss_config['bucket_name'].'.'.$oss_config['sts_endpoint'];
        $oss_cdn_arr = explode($oss_butkey_url, $url);

        if(count($oss_cdn_arr) > 1){
            $time = time()+$cdn_config['oss_cdn_expire_time']-600;
            $filename = $oss_cdn_arr[1];//"/add9/cover/20181217/201812179a847db72e4500e812d361edc70956441545031609992.png";
            $md5=md5($filename."-".$time."-0-0-".$cdn_config['oss_cdn_key']);
            $auth_key="auth_key=".$time."-0-0-".$md5;
            $url = 'http://'.$cdn_config['oss_cdn_url'].$filename."?".$auth_key;
        }
    }

    return $url;
}

/**
 * 判断操作系统 （0：windows系统  1：其他，例如linux）
 * @return int
 */
function getOS()
{
    if (strpos(strtolower(PHP_OS), 'win') !== false) {
        return 0;
    }

    return 1;
}

function clear_urlcan($url){

    $rstr='';

    $tmparr=parse_url($url);

    $rstr=empty($tmparr['scheme'])?'http://':$tmparr['scheme'].'://';

    $rstr.=$tmparr['host'].$tmparr['path'];

    return $rstr;

}

/*
 * 检测-创建目录
 * $path 目录的路径
 * */
function checkPath($path)
{
    // 创建目录
    if (!is_dir($path)){
        $res=mkdir(iconv("UTF-8", "GBK", $path),0777,true);
        if(!$res)
            return false;
    }

    return true;
}

/*
 * 身份证验证
 * */
function is_idcard( $id )
{
    $id = strtoupper($id);
    $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
    $arr_split = array();
    if(!preg_match($regx, $id))
    {
        return FALSE;
    }
    if(15==strlen($id)) //检查15位
    {
        $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";

        @preg_match($regx, $id, $arr_split);
        //检查生日日期是否正确
        $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
        if(!strtotime($dtm_birth))
        {
            return FALSE;
        } else {
            return TRUE;
        }
    }
    else      //检查18位
    {
        $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
        @preg_match($regx, $id, $arr_split);
        $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
        if(!strtotime($dtm_birth)) //检查生日日期是否正确
        {
            return FALSE;
        }
        else
        {
            //检验18位身份证的校验码是否正确。
            //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
            $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
            $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
            $sign = 0;
            for ( $i = 0; $i < 17; $i++ )
            {
                $b = (int) $id{$i};
                $w = $arr_int[$i];
                $sign += $b * $w;
            }
            $n = $sign % 11;
            $val_num = $arr_ch[$n];
            if ($val_num != substr($id,17, 1))
            {
                return FALSE;
            } //phpfensi.com
            else
            {
                return TRUE;
            }
        }
    }
}

/**
 * @param $strParam
 * @return null|string|string[]
 * 过滤特殊符号
 */
function replace_specialChar($strParam){
    $regex = "/\/|\～|\，|\。|\！|\？|\“|\”|\【|\】|\『|\』|\：|\；|\《|\》|\’|\‘|\ |\·|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\{|\}|\:|\<|\>|\?|\[|\]|\,|\.|\/|\;|\'|\`|\-|\=|\\\|\|/";
    return preg_replace($regex,"",$strParam);
}